package com.sqx.modules.health.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author Administrator
 */
public class DateUtil {

	public static final String FMT_YYYYMMDD = "yyyy-MM-dd";
	public static final String FMT_YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
	public static final String FMT_YYYYMMDD_HHMM = "yyyy-MM-dd HH:mm";
	public static final String FMT_HHMMSS = "HH:mm:ss";
	public static final String FMT_HHMM = "HH:mm";

	/**
	 * 日期转换为字符串格式
	 * @param date 日期
	 * @param pattern 格式模板
	 * @return 字符串日期
	 */
	public static String parseStr(Date date, String pattern) {

		if (date != null) {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			return sdf.format(date);
		}

		return "";
	}

	/**
	 * 字符串转换为日期
	 * @param value 日期字符串格式
	 * @param pattern  格式模板
	 * @return 日期
	 * @throws ParseException
	 */
	public static Date parseToDate(String value, String pattern)
			throws ParseException {

		if(!StringUtil.isEmpty(value)) {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			return sdf.parse(value);
		}

		return null;
	}

	/**
	 *
	 * @param lngDate 数字日期，转化为日期
	 * @return 日期  模板已经固定为"yyyy-MM-dd HH:mm:ss"
	 */
	public static Date longToDate(long lngDate) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = df.parse(df.format(new Date(lngDate)));
		} catch (ParseException e) {
		}
		return date;
	}

	/**
	 * 当前日期加减天数
	 *
	 * @param dateStr
	 * @param days
	 * @return
	 */
	public static String addDay(String dateStr, int days) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(FMT_YYYYMMDD);

			Calendar cd = Calendar.getInstance();
			cd.setTime(sdf.parse(dateStr));
			cd.add(Calendar.DATE, days);// 增加一天

			return sdf.format(cd.getTime());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 当前日期加减天数
	 *
	 * @param date
	 * @param days
	 * @return
	 */
	public static String addDay(Date date, int days) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(FMT_YYYYMMDD);

			Calendar cd = Calendar.getInstance();
			cd.setTime(date);
			cd.add(Calendar.DATE, days);// 增加一天

			return sdf.format(cd.getTime());
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 当前日期加减天数
	 *
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDays(Date date, int days) {
		try {
			Calendar cd = Calendar.getInstance();
			cd.setTime(date);
			cd.add(Calendar.DATE, days);// 增加一天

			return cd.getTime();
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 获取某日期的小时数
	 * @param date 给定日期
	 * @return
	 */
	public static int getHour(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取某日期的分钟数
	 * @param date 给定日期
	 * @return
	 */
	public static int getMinute(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}

	/**
	 * 比较两个日期是否是同一天
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean isSameDay(Date date1, Date date2) {
		return date1.getYear() == date2.getYear()
				&& date1.getMonth() == date2.getMonth()
				&& date1.getDate() == date2.getDate();
	}

	/**
	 * 比较两个日期相差多少分钟
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static long calculateMinute(Date endTime, Date startTime) {
		long between = (endTime.getTime() - startTime.getTime()) / 1000;// 除以1000是为了转换成秒
		long min = between / 60;
		return min;
	}
	/**
	 * 给定一个日期时间，比较是否在给定的另外两个日期之间
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static boolean betweenLocalDates(LocalDateTime inTime, LocalDateTime startTime, LocalDateTime endTime) {
		return (inTime.isAfter(startTime)&&inTime.isBefore(endTime));
	}
	/**
	 * 给定一个日期时间，比较是否在给定的另外两个日期之外
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static boolean outSideLocalDates(LocalDateTime inTime, LocalDateTime startTime, LocalDateTime endTime) {
		return (inTime.isAfter(endTime)||inTime.isBefore(startTime));
	}
	/**
	 * 给定一个日期时间，查找日期列表里最接近的日期时间
	 *
	 * @param inTime  基准日期
	 * @param datas 日期列表
	 * @return index 返回列表符合条件数据的索引
	 */

//	public static int checkNearLocalDate(LocalDateTime inTime, List<LocalDateTime> datas) {
//		long  times = 0,temp = 0;
//		int index = 0;
//		final long minss = 0;
//		for (int i = 0; i < datas.size(); i++) {
//			LocalDateTime a = datas.get(i);
//			Duration duration = Duration.between(a, inTime);
//			times = duration.toNanos();
//			if (temp > times) {
//				temp=times;
//				index=i;
//			}
//		}
// 		return index;
//	 }


	public static String checkNearLocalDate(String inTime, List<String> datas) {
		String flag=null;
		//2022-06-01 11:22:43 转化为 后面时间点为一个整数 112243, 比较08:00-09:00-1before 是否在时间区间
		//08:00-09:00-1before 转化为 两个整数 800*100    900*100  乘以100原因是系统不配置秒的数据.附加两位秒
		//然后比较 112243 是否 大于80000小于90000 成功就返回 1before
		int hour = Integer.parseInt(inTime.split(" ")[1].replace(":",""));

		for (int i = 0; i < datas.size(); i++) {
			int sd = Integer.parseInt(String.valueOf(datas.get(i)).split("-")[0].replace(":",""))*100;
			int ed = Integer.parseInt(String.valueOf(datas.get(i)).split("-")[1].replace(":",""))*100;
			flag =  String.valueOf(datas.get(i)).split("-")[2];
			if(hour>=sd && hour<=ed){
				return flag;
			}
		}
		return flag;
	}

	/**
	 * 日期转星期
	 *
	 * @param datetime
	 * @return
	 */
	public static String dateToWeek(String datetime) {

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
		Calendar cal = Calendar.getInstance(); // 获得一个日历

		try {
			cal.setTime(format.parse(datetime));
		} catch (ParseException e) {
		}

		int index = cal.get(Calendar.DAY_OF_WEEK) - 1; // 指示一个星期中的某天。

		if (index < 0) {
			index = 0;
		}

		return weekDays[index];
	}

	/**
	 * 比较日期大小
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int compareDate(Date date1, Date date2) {

		try {
			if (date1.getTime() > date2.getTime()) {
				return 1;
			} else if (date1.getTime() < date2.getTime()) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
		}

		return 0;
	}

	/**
	 * 获得当天的起始时间
	 *
	 * @return
	 */
	public static Calendar getStartDate(Calendar today) {
		today.set(Calendar.HOUR_OF_DAY, 0);
		today.set(Calendar.MINUTE, 0);
		today.set(Calendar.SECOND, 0);
		today.set(Calendar.MILLISECOND, 0);
		return today;
	}

	public static Date getBeginToDayDate(Date today) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(today);
		Calendar calendarNow = getStartDate(calendar);
		return calendarNow.getTime();
	}

	/**
	 * 获取当天截止时间
	 *
	 * @return
	 */
	public static Calendar getEndDate(Calendar endToday) {
		endToday.set(Calendar.HOUR_OF_DAY, 23);
		endToday.set(Calendar.MINUTE, 59);
		endToday.set(Calendar.SECOND, 59);
		endToday.set(Calendar.MILLISECOND, 59);
		return endToday;
	}

	public static Date getEndTodayDate(Date endToday) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(endToday);
		Calendar calendarNow = getEndDate(calendar);
		return calendarNow.getTime();
	}

	/**
	 * 获得当月起始时间
	 *
	 * @return
	 */
	public static Calendar getStartMounth(Calendar today) {
		Calendar calendar = getStartDate(today);
		calendar.set(Calendar.DAY_OF_MONTH,
				calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
		return calendar;
	}

	/**
	 * 获得当月结束时间
	 *
	 * @return
	 */
	public static Calendar getEndMounth(Calendar endToday) {
		Calendar endMounth = getEndDate(endToday);
		endMounth.set(Calendar.DAY_OF_MONTH,
				endMounth.getActualMaximum(endMounth.DAY_OF_MONTH));
		return endMounth;
	}

	/**
	 * 获取当前季度 起始时间
	 *
	 * @return
	 */
	public static Calendar getStartQuarter(Calendar today) {
		int currentMonth = today.get(Calendar.MONTH) + 1;
		try {
			if (currentMonth >= 1 && currentMonth <= 3)
				today.set(Calendar.MONTH, 0);
			else if (currentMonth >= 4 && currentMonth <= 6)
				today.set(Calendar.MONTH, 3);
			else if (currentMonth >= 7 && currentMonth <= 9)
				today.set(Calendar.MONTH, 4);
			else if (currentMonth >= 10 && currentMonth <= 12)
				today.set(Calendar.MONTH, 9);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return today;
	}

	/**
	 * 获取当季的结束时间
	 */
	public static Calendar getEndQuarter(Calendar today) {
		int currentMonth = today.get(Calendar.MONTH) + 1;
		try {
			if (currentMonth >= 1 && currentMonth <= 3) {
				today.set(Calendar.MONTH, 2);
				today.set(Calendar.DATE, 31);
			} else if (currentMonth >= 4 && currentMonth <= 6) {
				today.set(Calendar.MONTH, 5);
				today.set(Calendar.DATE, 30);
			} else if (currentMonth >= 7 && currentMonth <= 9) {
				today.set(Calendar.MONTH, 8);
				today.set(Calendar.DATE, 30);
			} else if (currentMonth >= 10 && currentMonth <= 12) {
				today.set(Calendar.MONTH, 11);
				today.set(Calendar.DATE, 31);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return today;
	}

	/**
	 * 获取当年起始时间
	 */
	public static Calendar getStartYear(Calendar today) {
		try {
			today.set(Calendar.MONTH, 0);
			today.set(Calendar.DAY_OF_MONTH,
					today.getActualMinimum(Calendar.DAY_OF_MONTH));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return today;
	}

	/**
	 * 获取当年结束时间
	 */
	public static Calendar getEndYear(Calendar today) {
		try {
			today.set(Calendar.MONTH, 11);
			today.set(Calendar.DAY_OF_MONTH,
					today.getMaximum(Calendar.DAY_OF_MONTH));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return today;
	}

	/**
	 * 比较两个日期间隔天数
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static int calculateDays(Date endTime, Date startTime) {
		long between = (endTime.getTime() - startTime.getTime()) / 1000; // 除以1000是为了转换成秒
		long days = between / 3600 / 24;

		return (int) days;
	}

	/**
	 * 计算日期间隔是否超过1年
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static boolean exceedOneYear(Date endTime, Date startTime) {
		if (null == startTime) {
			return true;
		}

		if (null == endTime) {
			endTime = new Date();
		}

		Calendar cd = Calendar.getInstance();
		cd.setTime(startTime);
		cd.add(Calendar.YEAR, 1);

		return 0 < compareDate(endTime, cd.getTime());
	}

	/**
	 * 计算日期间隔是否超过365天
	 *
	 * @param endTime
	 * @param startTime
	 * @return
	 */
	public static boolean exceedOneYear(String endTime, String startTime,
										String timeFormat) {

		if (StringUtil.isEmpty(startTime)) {
			return true;
		}

		try {
			Date $startTime = parseToDate(startTime, timeFormat);
			Date $endTime = (StringUtil.isEmpty(endTime)) ? new Date()
					: parseToDate(endTime, timeFormat);

			return exceedOneYear($endTime, $startTime);
		} catch (ParseException e) {
			return false;
		}
	}

	/**
	 * 获取当天的结束时间
	 *
	 * @param endDate
	 * @param dateFormat
	 * @return
	 */
	public static String getEndDate(String endDate, String dateFormat) {

		if (StringUtil.isEmpty(endDate)) {
			return null;
		}

		try {
			Date $endDate = parseToDate(endDate, dateFormat);

			return parseStr(getEndTodayDate($endDate), FMT_YYYYMMDD_HHMMSS);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取当天的开始时间
	 *
	 * @param beginDate
	 * @param dateFormat
	 * @return
	 */
	public static String getStartDate(String beginDate, String dateFormat) {

		if (StringUtil.isEmpty(beginDate)) {
			return null;
		}

		try {
			Date $beginDate = parseToDate(beginDate, dateFormat);

			return parseStr(getBeginToDayDate($beginDate), FMT_YYYYMMDD_HHMMSS);
		} catch (ParseException e) {
			return beginDate;
		}
	}

	/**
	 * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
	 *
	 * @param nowTime 当前时间
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 * @author yek
	 */
	public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
		if (nowTime.getTime() == startTime.getTime()) {
			return true;
		}

		Calendar date = Calendar.getInstance();
		date.setTime(nowTime);

		Calendar begin = Calendar.getInstance();
		begin.setTime(startTime);

		Calendar end = Calendar.getInstance();
		end.setTime(endTime);

		if (date.after(begin) && date.before(end)) {
			return true;
		} else {
			return false;
		}
	}

	public static String getDateTimeAsString(LocalDateTime localDateTime, String format) {
      DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
    return localDateTime.format(formatter);
	}
	public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
      Instant instant = Instant.ofEpochMilli(timestamp);
      ZoneId zone = ZoneId.systemDefault();
      return LocalDateTime.ofInstant(instant, zone);
	}
	public static LocalDateTime parseStringToDateTime(String time, String format) {
      DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
      return LocalDateTime.parse(time, df);
	}
	public static long getTimestampOfDateTime(LocalDateTime localDateTime) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return instant.toEpochMilli();
	}

	public static List<Date> getDaysBetweenDates(String startDate, String endDate) throws ParseException {
		List<Date> dates = new ArrayList<Date>();
		Calendar calendar = new GregorianCalendar();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		calendar.setTime(format.parse(startDate));

		while (calendar.getTime().before(format.parse(endDate))) {
			Date result = calendar.getTime();
			dates.add(result);
			calendar.add(Calendar.DATE, 1);
		}
		return dates;
	}

	public static List<String> getDaysStringBetweenDates(String startDateString, String endDateString) throws ParseException {
		List<String> dates = new ArrayList<String>();
		Calendar calendar = new GregorianCalendar();
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date endDate = format.parse(endDateString);
		Date startDate = format.parse(startDateString);
		calendar.setTime(startDate);

		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
		while (calendar.getTime().before(endDate)) {
			Date result = calendar.getTime();
			dates.add(sdf.format(result));
			calendar.add(Calendar.DATE, 1);
		}
		dates.add(sdf.format(endDate));
		return dates;
	}


	public static void main(String[] args) throws Exception {
		//System.out.println(getEndDate("2018-10-02",FMT_YYYYMMDD));
		//System.out.println(getStartDate("2018-10-02",FMT_YYYYMMDD));
		System.out.println(getDaysStringBetweenDates("2023-10-10", "2023-10-20"));
	}
}
